﻿using FastReport.Data;
using FastReport.Export.Pdf;
using FreeSql;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Volo.Abp;
using Volo.Abp.Application.Services;

namespace Colorful.Furniture.ReportManagement;

/// <summary>
///  报表服务
/// </summary>
public class ReportAppService : ApplicationService
{
    private readonly IBaseRepository<Report> _reportsRepository;
    private readonly IFreeSql _freeSql;
    private readonly IDatabase _redisDb;
    private readonly ILogger<ReportAppService> _logger;
    private readonly IConfiguration _configuration;

    public ReportAppService(IBaseRepository<Report> reportsRepository,
        IFreeSql freeSql,
        IConnectionMultiplexer connectionMultiplexer,
        ILogger<ReportAppService> logger,
        IConfiguration configuration)
    {
        _reportsRepository = reportsRepository;
        _freeSql = freeSql;
        _logger = logger;
        _configuration = configuration;
        _redisDb = connectionMultiplexer.GetDatabase();
    }

    /// <summary>
    ///  报表类
    /// </summary>
    public class ReportPreviewParam
    {
        /// <summary>
        ///  报表代码
        /// </summary>
        public string ReportCode { get; set; }

        /// <summary>
        ///  参数集合
        /// </summary>
        public List<ReportParameter> Parameters { get; set; }
    }

    /// <summary>
    ///  报表参数
    /// </summary>
    public class ReportParameter
    {
        /// <summary>
        ///  参数的键
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        ///  参数的值
        /// </summary>
        public object Value { get; set; }
    }

    /// <summary>
    ///  预览报表pdf
    /// </summary>
    /// <param name="hostEnvironment">环境棉量</param>
    /// <param name="previewParams">预览参数json</param>
    /// <returns></returns>
    [HttpGet("/report/preview-pdf/{reportName}")]
    public async Task<IActionResult> BillPreviewPdfAsync([FromServices] IWebHostEnvironment hostEnvironment, string previewParams)
    {
        if (string.IsNullOrWhiteSpace(previewParams))
            throw new ArgumentNullException($"报表预览参数：{nameof(previewParams)} 不能为空");

        var previewParamList = JsonConvert.DeserializeObject<List<ReportPreviewParam>>(previewParams);

        if (previewParamList == null || !previewParamList.Any())
            throw new ArgumentNullException($"报表预览参数：{nameof(previewParams)} 不能为空");

        var report = new FastReport.Report();

        foreach (var reportPreviewParam in previewParamList)
        {
            var reportInfo = await _reportsRepository
                .Where(x => x.Code == reportPreviewParam.ReportCode)
                .ToOneAsync();

            if (reportInfo == null)
                throw new UserFriendlyException($"报表{reportPreviewParam.ReportCode}不存在");

            if (string.IsNullOrWhiteSpace(reportInfo.Url))
                throw new UserFriendlyException("报表文件路径不存在");

            //判断如果url为http在线地址，则不需要进行拼接
            string reportXml;
            if (reportInfo.Url.Contains("http://") || reportInfo.Url.Contains("https://"))
                reportXml = reportInfo.Url;
            else
                reportXml = Path.Combine(hostEnvironment.WebRootPath, reportInfo.Url);

            report.Load(reportXml);

            foreach (var parameter in reportPreviewParam.Parameters)
            {
                report.SetParameterValue(parameter.Key, parameter.Value);
            }

            if (reportInfo.Name == "订货单")
            {
                var dataSet = new DataSet();
                foreach (var connection in report.Dictionary.Connections.Cast<MsSqlDataConnection>())
                {
                    var dataTableSource = connection.Tables.Cast<TableDataSource>().ToList();
                    foreach (var tableDataSource in dataTableSource)
                    {
                        var sqlCommand = tableDataSource.SelectCommand;

                        var dataTable = await _freeSql.Select<object>()
                            .WithSql(sqlCommand, reportPreviewParam.Parameters.ToDictionary(x => x.Key, x => x.Value))
                            .ToDataTableAsync("*");

                        //单独处理 配置清单项的图册
                        if (tableDataSource.Name == "配置清单项" || tableDataSource.Alias == "配置清单项")
                        {
                            foreach (DataRow dataTableRow in dataTable.Rows)
                            {
                                if (!string.IsNullOrWhiteSpace(dataTableRow["图册"].ToString()))
                                {
                                    var ht = new HttpClient();

                                    var stream = await ht.GetStreamAsync(dataTableRow["图册"].ToString());

                                    var byteArray = await stream.GetAllBytesAsync();

                                    dataTableRow["图册"] = byteArray;
                                }
                            }
                        }

                        dataSet.Tables.Add(dataTable);
                    }
                }

                report.RegisterData(dataSet);
            }

            report.Prepare(true);
        }

        using var pdfExport = new PDFExport();

        pdfExport.OpenAfterExport = false;
        pdfExport.ShowPrintDialog = false;
        pdfExport.ExportMode = PDFExport.ExportType.WebPrint;

        await using var ms = new MemoryStream();

        pdfExport.Export(report, ms);

        var bytes = ms.ToArray();

        return new FileContentResult(bytes, "application/pdf");
    }
}